#define LG_CORE

#include "lg_texture.h"
#include "lodepng.h"

struct {
    LGConfig* config;
    LGTextureBackend* backend;
}ctx = { 0 };

LG_API void
lgInitTextureContext(
    LGConfig* config, LGTextureBackend* backend) {
    ctx.config = config;
    ctx.backend = backend;
}

static void
freeTexture(LGRef* ref) {
    LGTexture* tex = (LGTexture*)ref;
    ctx.backend->freeTexture(tex);
}

LG_API LGTexture*
lgNewTexture(unsigned width, unsigned height, LGTexFormat format) {
    size_t size = ctx.backend->sizeofTexture();
    LGTexture* tex = lgNewRef(size, freeTexture);
    tex->width = width;
    tex->height = height;
    tex->format = format;
    tex->minFilter = LGTEX_FILTER_LINEAR;
    tex->maxFilter = LGTEX_FILTER_LINEAR;
    tex->sWrap = LGTEX_WRAP_BORDER;
    tex->sWrap = LGTEX_WRAP_BORDER;
    ctx.backend->newTexture(tex);
    return tex;
}

LG_API LGTexture*
lgNewPngTexture(const char* data, size_t size) {
    unsigned error;
    unsigned char* image = NULL;
    unsigned width, height;
    error = lodepng_decode32(&image, &width, &height, data, size);
    if (error) {
        if (image) { free(image); }
        return NULL;
    }
    LGTexture* tex = lgNewTexture(width, height, LGTEX_RGBA);
    unsigned rect[] = { 0, 0, width, height };
    lgUploadTexture(tex, LGTEX_RGBA, rect, image);
    free(image);
    return tex;
}

LG_API void
lgFreeTexture(LGTexture* tex) {
    ctx.backend->freeTexture(tex);
    free(tex);
}

LG_API int
lgUploadTexture(LGTexture* tex,
    int format, unsigned rect[4], const void* data){
    return ctx.backend->uploadPixel(tex, format, rect, data);
}

LG_API void
lgTextureFilter(LGTexture* tex,
    LGTexFilter minFilter, LGTexFilter maxFilter) {
    tex->minFilter = minFilter;
    tex->maxFilter = maxFilter;
    ctx.backend->setFilter(tex);
}
LG_API void
lgTextureWrap(LGTexture* tex,
    LGTexWrap sWrap, LGTexWrap tWrap) {
    tex->sWrap = sWrap;
    tex->tWrap;
    ctx.backend->setWrap(tex);
}
